﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Bio.Web.Blast;
using System.IO;

namespace CandyBlast
{
    public class NcbiBlastImporter 
    {



        public bool Import(int jobId, string blastXml, int projectId, out string error)
        {
            error = null;
            IEnumerable<BlastResult> blastResults = null;
            try
            {
                TextReader sr = new StringReader(blastXml);
                IBlastParser blastXmlParser = new BlastXmlParser();
                blastResults = blastXmlParser.Parse(sr);
            }
            catch (Exception ex)
            {
                error = ex.Message;
                return false;
            }

            return Import(jobId, blastResults, projectId, out error);
            
        }


        public bool Import(int jobId, IEnumerable<BlastResult> blastResults, int projectId, out string error)
        {
            error = null;
            try
            {
                //get all hits
                List<TopHit> allHits = new List<TopHit>();
                foreach (var r in blastResults)
                {
                    foreach (var record in r.Records)
                    {
                        foreach (var hit in record.Hits)
                        {
                            TopHit pv = new TopHit();
                         //   pv.UId = Guid.NewGuid();
                            pv.BlastJobId = jobId;
                           
                            Hsp hsp = hit.Hsps.First();
                            pv.HspsCounter = hit.Hsps.Count();
                            pv.RequestingGeneId = int.Parse(record.IterationQueryDefinition);
                            pv.GeneId = hit.Def;
                            pv.Identity = (int)hsp.IdentitiesCount;
                            pv.Length = (int)hit.Length;
                            pv.MatchSeq = hsp.HitSequence;
                            pv.QuerySeq = hsp.QuerySequence;
                            pv.Pattern = hsp.Midline;
                            pv.Positives = (int)hsp.PositivesCount;
                            pv.Probability = hsp.EValue;
                            pv.Expectation = hsp.EValue;
                            pv.Score = (int)Math.Floor(hsp.Score);

                            allHits.Add(pv);
                        }

                    }
                }

                //agregate to all top hits
                var hitIds = allHits.Select(x => x.GeneId).Distinct();
                List<TopHit> aggregatedHits = new List<TopHit>();
                foreach (var id in hitIds)
                {
                    var h = allHits.Where(x => x.GeneId == id).ToList();
                    TopHit bestHit = h.First();

                    foreach (var item in h)
                    {
                        if (item.Expectation < bestHit.Expectation)
                            bestHit = item;
                    }
                    bestHit.GeneHitCounter = h.Count;
                    aggregatedHits.Add(bestHit);
                }

                using (CandyDBDataContext context = new CandyDBDataContext(ProjectConnector.GetCandyConnectionString(projectId)))
                {
                    context.TopHits.InsertAllOnSubmit(aggregatedHits);
                    context.SubmitChanges();

                }


                return true;
            }
            catch (Exception ex)
            {
                error = ex.Message;
                return false;
            }
        }
    }
}
